#ifndef _TCPIP_AT_H
#define _TCPIP_AT_H

#define CTX_DEF       1       //默认场景号
#define CTX_DEACTS    3       //去激活失败次数
#define MAX_IP_LEN    16
#define QIOPENTO      150000  //套接字open超时时间,单位毫秒
#define QIOPENTS      5       //套接字open失败次数
#define QICLOSETO     10      //套接字close超时时间,单位秒
#define ACKTO         5000    //查询ack周期,单位毫秒
#define ACKTS         24      //查询ack次数

#pragma pack(1)
typedef enum
{
    CTX_INIT=0,
    CTX_ACT,
    CTX_DEACT,
    CTX_READY,
    CTX_UNKNOW
}EN_EC600S_CTX;

typedef struct
{
    char dstAddr[MAX_IP_LEN];
    U16 port;
}EC600S_ADDR;

typedef enum
{
    SOCK_TCP=0,
    SOCK_UDP,
    SOCK_UNKNOW
}EN_SOCK_TYPE;

typedef enum
{
    EN_DATA_TYPE_STR=0,
    EN_DATA_TYPE_HEX,
    EN_DATA_TYPE_MAX,
}EN_EC600S_DATA_TYPE;

typedef struct
{
    int tsl;    //发送数据总长度. 单位:字节
    int ack;    //ACK字节数
    int unack;  //未ACK字节数
}ST_QISEND0;

typedef struct
{
    int len;
    U8 data[1460];
}ST_QIRD;

typedef struct
{
    int total_receive_length;
    int have_read_length;
    int unread_length;
}ST_QIRD0;

#pragma pack()

/**
@brief TCPIP场景初始化
@param
@return 0成功,非0失败
**/
int Ec600sCtxInit();
/**
@brief TCPIP QIOPEN操作函数
@param sock 套接字
@param sock_type 套接字类型
@param to_addr 目的地址
@param local_addr 本地地址
@return
**/
int Ec600sAT_QIOPEN(int sock,EN_SOCK_TYPE sock_type,EC600S_ADDR *to_addr,EC600S_ADDR *local_addr);
/**
@brief TCPIP QICLOSE操作函数
@param sock 套接字
@return
**/
int Ec600sAT_QICLOSE(int sock);
/**
@brief TCPIP QISEND操作函数
@param sock 套接字
@param len 数据长度
@return
**/
int Ec600sAT_QISEND(int sock,int len);
/**
@brief 发送数据
@param sock 套接字
@param data 数据内容
@param len  数据长度
@return 0.若连接已经建立，且发送成功,-99.若连接已经建立，但是发送缓存已满,-98.若连接未建立、 异常断开或者参数不正确
**/
int Ec600sAT_SendData(U8 data[], int len);
/**
@brief 发送16进制数据
@param sock 套接字
@param data 数据内容
@param len  数据长度
@return 0.若连接已经建立，且发送成功,-99.若连接已经建立，但是发送缓存已满,-98.若连接未建立、 异常断开或者参数不正确
**/
int Ec600sAT_QISENDEX(int sock,U8 data[],int len);
/**
@brief 查询已发送字节数
@param sock 套接字
@param obuf 套接字发送结果
@return 0.成功,非0失败
**/
int Ec600sAT_QISEND0(int sock, char *obuf);
/**
@brief 入队列操作,去激活场景,URC[pdpdeact]调用
@param ctx 场景ID
@return 0.成功,非0失败
**/
int Ec600sAT_QIDEACT_QIN(int ctx);
/**
@brief 入队列操作,关闭套接字
@param sock 套接字
@return 0.成功,非0失败
**/
int Ec600sAT_QICLOSE_QIN(int sock);
/**
@brief ec600s tcpip模块初始化
@param 无
@return
**/
void Ec600sTcpipInit();
/**
@brief 获取场景状态
@return 当前场景状态
**/
EN_EC600S_CTX Ec600sCtxGet();
/**
@brief 设置场景状态
@param ctx 场景状态
@return
**/
void Ec600sCtxSet(EN_EC600S_CTX ctx);
/**
@brief TCPIP场景主处理函数
@param
@return
**/
int Ec600sCtxLoop();
/**
@brief 打开套接字超时处理函数
@param flags 0.倒计时中... 1.开始超时倒计时计算 2.打开套接字成功关闭开始倒计时 3.打开套接字失败关闭开始倒计时
@return
**/
int Ec600sQIOPENTo(int s, int flags);

/**
@brief TCP ACK超时处理函数,被Ec600sDataSend调用
@param s 套接字
@param flags 0.等待确认ACK消息,s无效 1.设置套接字,重新开始确认ACK消息, 2.关闭ACK倒计时
@return
**/
int Ec600sTcpAckTo(int s, int flags);
/**
@brief EC600S TCPIP主处理函数
@param
@return
**/
int Ec600sTcpipLoop();
/**
@brief 套接字是否有数据待接收
@param s套接字
@param has 0.无数据,1.有数据
@return
**/
int Ec600sSockHasDataSet(int s, int has);

#endif

